const jwt = require('jsonwebtoken');
const logger = require('./logger');

/**
 * 生成访问令牌
 * @param {Object} payload - 令牌载荷
 * @param {string} expiresIn - 过期时间
 */
const generateAccessToken = (payload, expiresIn = null) => {
  try {
    const options = {
      expiresIn: expiresIn || process.env.JWT_EXPIRES_IN || '24h'
    };

    return jwt.sign(payload, process.env.JWT_SECRET, options);
  } catch (error) {
    logger.error('生成访问令牌失败:', { error: error.message });
    throw new Error('令牌生成失败');
  }
};

/**
 * 生成刷新令牌
 * @param {Object} payload - 令牌载荷
 */
const generateRefreshToken = (payload) => {
  try {
    const options = {
      expiresIn: process.env.JWT_REFRESH_EXPIRES_IN || '7d'
    };

    return jwt.sign(payload, process.env.JWT_REFRESH_SECRET, options);
  } catch (error) {
    logger.error('生成刷新令牌失败:', { error: error.message });
    throw new Error('刷新令牌生成失败');
  }
};

/**
 * 验证访问令牌
 * @param {string} token - 要验证的令牌
 */
const verifyAccessToken = (token) => {
  try {
    return jwt.verify(token, process.env.JWT_SECRET);
  } catch (error) {
    logger.debug('访问令牌验证失败:', { 
      error: error.message,
      tokenExpired: error.name === 'TokenExpiredError'
    });
    throw error;
  }
};

/**
 * 验证刷新令牌
 * @param {string} token - 要验证的刷新令牌
 */
const verifyRefreshToken = (token) => {
  try {
    return jwt.verify(token, process.env.JWT_REFRESH_SECRET);
  } catch (error) {
    logger.debug('刷新令牌验证失败:', { 
      error: error.message,
      tokenExpired: error.name === 'TokenExpiredError'
    });
    throw error;
  }
};

/**
 * 解码令牌（不验证）
 * @param {string} token - 要解码的令牌
 */
const decodeToken = (token) => {
  try {
    return jwt.decode(token);
  } catch (error) {
    logger.error('令牌解码失败:', { error: error.message });
    return null;
  }
};

/**
 * 从请求头获取令牌
 * @param {Object} req - Express请求对象
 */
const extractTokenFromHeader = (req) => {
  const authHeader = req.headers.authorization;
  
  if (!authHeader) {
    return null;
  }

  const parts = authHeader.split(' ');
  
  if (parts.length !== 2 || parts[0] !== 'Bearer') {
    return null;
  }

  return parts[1];
};

/**
 * 生成令牌对
 * @param {Object} user - 用户对象
 */
const generateTokenPair = (user) => {
  const payload = {
    userId: user._id,
    email: user.email,
    role: user.role,
    address: user.address
  };

  const accessToken = generateAccessToken(payload);
  const refreshToken = generateRefreshToken({ userId: user._id });

  return {
    accessToken,
    refreshToken,
    expiresIn: process.env.JWT_EXPIRES_IN || '24h'
  };
};

/**
 * 验证令牌是否即将过期
 * @param {string} token - 要检查的令牌
 * @param {number} thresholdMinutes - 过期阈值（分钟）
 */
const isTokenExpiringSoon = (token, thresholdMinutes = 30) => {
  try {
    const decoded = decodeToken(token);
    if (!decoded || !decoded.exp) {
      return false;
    }

    const expirationTime = decoded.exp * 1000; // 转换为毫秒
    const currentTime = Date.now();
    const thresholdTime = thresholdMinutes * 60 * 1000; // 转换为毫秒

    return (expirationTime - currentTime) < thresholdTime;
  } catch (error) {
    logger.error('检查令牌过期时间失败:', { error: error.message });
    return false;
  }
};

/**
 * 获取令牌剩余有效时间（秒）
 * @param {string} token - 令牌
 */
const getTokenRemainingTime = (token) => {
  try {
    const decoded = decodeToken(token);
    if (!decoded || !decoded.exp) {
      return 0;
    }

    const expirationTime = decoded.exp;
    const currentTime = Math.floor(Date.now() / 1000);

    return Math.max(0, expirationTime - currentTime);
  } catch (error) {
    logger.error('获取令牌剩余时间失败:', { error: error.message });
    return 0;
  }
};

module.exports = {
  generateAccessToken,
  generateRefreshToken,
  verifyAccessToken,
  verifyRefreshToken,
  decodeToken,
  extractTokenFromHeader,
  generateTokenPair,
  isTokenExpiringSoon,
  getTokenRemainingTime
};